﻿#nullable enable
using System.Collections.Generic;

using Acl.Data.Mappings;
using Acl.Dynamic;

namespace Acl.Excel
{
    /// <summary>
    ///  Xlsx 文件读写类
    /// </summary>
    public static class ExcelFile
    {
        /// <summary>
        /// 查询工作表
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="excelFile"></param>
        /// <param name="sheetName"></param>
        /// <returns></returns>
        public static IEnumerable<TModel> Query<TModel>(string excelFile, string? sheetName = null) where TModel : new()
        {
            var options = new ExcelQueryOptions
            {
                ExcelFile = excelFile,
                SheetName = sheetName,
            };

            var workbook = new Workbook(excelFile);
            return workbook.Read<TModel>(options);
        }

        /// <summary>
        /// 查询工作表
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="excelFile"></param>
        /// <param name="sheetName"></param>
        /// <param name="columnSize"></param>
        /// <returns></returns>
        public static IEnumerable<TModel> Query<TModel>(string excelFile, string sheetName, uint columnSize) where TModel : new()
        {
            var options = new ExcelQueryOptions
            {
                ExcelFile = excelFile,
                SheetName = sheetName,
                ColumnSize = columnSize
            };

            var workbook = new Workbook(excelFile);
            return workbook.Read<TModel>(options);
        }

        /// <summary>
        /// 查询工作表
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="excelFile"></param>
        /// <param name="sheetName"></param>
        /// <param name="columnSize"></param>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static IEnumerable<TModel> Query<TModel>(string excelFile, string sheetName, uint columnSize, ColumnMappingBuilder? builder) where TModel : new()
        {
            var options = new ExcelQueryOptions
            {
                ExcelFile = excelFile,
                SheetName = sheetName,
                ColumnSize = columnSize,
            };

            options.MappingBuilder = builder;

            var workbook = new Workbook(excelFile);
            return workbook.Read<TModel>(options);
        }

        ///// <summary>
        ///// 查询工作表
        ///// </summary>
        ///// <typeparam name="TModel"></typeparam>
        ///// <param name="excelFile"></param>
        ///// <param name="sheetName"></param>
        ///// <param name="rowSize"></param>
        ///// <param name="columnSize"></param>
        ///// <param name="startRowNumber"></param>
        ///// <param name="startColumnNumber"></param>
        ///// <param name="builder"></param>
        ///// <param name="hasHeader"></param>
        ///// <returns></returns>
        //public static IEnumerable<TModel> Query<TModel>(string excelFile,
        //    string sheetName = null,
        //    uint? rowSize = null,
        //    uint? columnSize = null,
        //    uint startRowNumber = 1,
        //    uint startColumnNumber = 1,
        //    ColumnMappingBuilder builder = null,
        //    bool hasHeader = true)
        //    where TModel : new() {
        //    var options = new ExcelQueryOptions
        //    {
        //        ExcelFile = excelFile,
        //        SheetName = sheetName,
        //        RowSize = rowSize,
        //        ColumnSize = columnSize,
        //        StartColumnNumber = startColumnNumber,
        //        StartRowNumber = startRowNumber,
        //        MappingBuilder = builder,
        //        HasHeader = hasHeader
        //    };

        //    var workbook = new Workbook(excelFile);
        //    return workbook.Read<TModel>(options);
        //}

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="options"></param>
        /// <returns></returns>
        public static IEnumerable<TModel> Query<TModel>(ExcelQueryOptions options) where TModel : new()
        {
            Guard.NotNull(options, nameof(options));
            var workbook = new Workbook(options.ExcelFile);
            return workbook.Read<TModel>(options);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public static DynamicEntitySet Query(ExcelQueryOptions options)
        {
            Guard.NotNull(options, nameof(options));
            var workbook = new Workbook(options.ExcelFile);
            return workbook.Read(options);
        }

        /// <summary>
        /// 查询工作表
        /// </summary>
        /// <param name="excelFile"></param>
        /// <param name="sheetName"></param>
        /// <returns></returns>
        public static DynamicEntitySet Query(string excelFile, string sheetName)
        {
            var options = new ExcelQueryOptions
            {
                ExcelFile = excelFile,
                SheetName = sheetName,
            };

            var workbook = new Workbook(excelFile);
            return workbook.Read(options);
        }

        /// <summary>
        /// 查询工作表
        /// </summary>
        /// <param name="excelFile"></param>
        /// <param name="sheetName"></param>
        /// <param name="columnSize"></param>
        /// <returns></returns>
        public static DynamicEntitySet Query(string excelFile, string sheetName, uint columnSize)
        {
            var options = new ExcelQueryOptions
            {
                ExcelFile = excelFile,
                SheetName = sheetName,
                ColumnSize = columnSize
            };

            var workbook = new Workbook(excelFile);
            return workbook.Read(options);
        }

        ///// <summary>
        ///// 查询工作表
        ///// </summary>
        ///// <param name="excelFile"></param>
        ///// <param name="sheetName"></param>
        ///// <param name="rowSize"></param>
        ///// <param name="columnSize"></param>
        ///// <param name="startRowNumber"></param>
        ///// <param name="startColumnNumber"></param>
        ///// <param name="hasHeader"></param>
        ///// <returns></returns>
        //public static Acl.Dynamic.DynamicEntitySet Query(string excelFile,
        //    string sheetName,
        //    uint? rowSize,
        //    uint? columnSize = null,
        //    uint startRowNumber = 1,
        //    uint startColumnNumber = 1,
        //    bool hasHeader = true) {
        //    var options = new ExcelQueryOptions
        //    {
        //        ExcelFile = excelFile,
        //        SheetName = sheetName,
        //        RowSize = rowSize,
        //        ColumnSize = columnSize,
        //        StartColumnNumber = startColumnNumber,
        //        StartRowNumber = startRowNumber,
        //        HasHeader = hasHeader
        //    };

        //    var workbook = new Workbook(excelFile);

        //    return workbook.Read(options);
        //}

        /// <summary>
        /// 加载工作薄中内容到动态实体集合中
        /// </summary>
        /// <param name="models">实体集合</param>
        /// <param name="excelFile"></param>
        /// <param name="sheetName">工作薄名称</param>
        /// <param name="rowSize"></param>
        /// <param name="columnSize">列大小</param>
        /// <param name="startRowNumber">起始行编号</param>
        /// <param name="startColumnNumber">起始列编号</param>
        public static void Fill<TModel>(IList<TModel> models,
            string excelFile,
            string? sheetName = null,
            uint? rowSize = null,
            uint? columnSize = null,
            uint startRowNumber = 1,
            uint startColumnNumber = 1)
            where TModel : new()
        {
            var options = new ExcelQueryOptions
            {
                ExcelFile = excelFile,
                SheetName = sheetName,
                RowSize = rowSize,
                ColumnSize = columnSize,
                StartColumnNumber = startColumnNumber,
                StartRowNumber = startRowNumber,
            };
            new Workbook(excelFile).Fill(models, options);
        }

        /// <summary>
        /// 加载工作薄中内容到动态实体集合中
        /// </summary>
        /// <param name="entitySet">实体集合</param>
        /// <param name="excelFile"></param>
        /// <param name="sheetName">工作薄名称</param>
        /// <param name="rowSize"></param>
        /// <param name="columnSize">列大小</param>
        /// <param name="startRowNumber">起始行编号</param>
        /// <param name="startColumnNumber">起始列编号</param>
        public static void Fill(DynamicEntitySet entitySet,
            string excelFile,
            string? sheetName = null,
            uint? rowSize = null,
            uint? columnSize = null,
            uint startRowNumber = 1,
            uint startColumnNumber = 1)
        {
            var options = new ExcelQueryOptions
            {
                ExcelFile = excelFile,
                SheetName = sheetName,
                RowSize = rowSize,
                ColumnSize = columnSize,
                StartColumnNumber = startColumnNumber,
                StartRowNumber = startRowNumber,
            };

            new Workbook(excelFile).Fill(entitySet, options);
        }

        /// <summary>
        /// 加载工作薄中内容到动态实体集合中
        /// </summary>
        /// <param name="entitySet">实体集合</param>
        /// <param name="options"></param>
        public static void Fill(DynamicEntitySet entitySet,
           ExcelQueryOptions options)
        {
            new Workbook(options.ExcelFile).Fill(entitySet, options);
        }

        /// <summary>
        /// 保存工作表
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="models"></param>
        /// <param name="excelFile"></param>
        /// <param name="sheetName"></param>
        /// <param name="builder"></param>
        /// <param name="append"></param>
        public static void Write<TModel>(
          IEnumerable<TModel> models,
          string excelFile,
          string? sheetName = null,
          IColumnNameMappingBuilder<TModel>? builder = null,
          bool append = false)
        {
            var workbook = new Workbook(excelFile);
            workbook.Write(models, sheetName, builder as ColumnMappingBuilder, append);
            workbook.Save();
        }

        /// <summary>
        /// 向工作薄写入内容，覆盖工作薄中原有内容
        /// </summary>
        /// <param name="entitySet"></param>
        /// <param name="excelFile"></param>
        /// <param name="sheetName"></param>
        /// <param name="append"></param>
        public static void Write(
            DynamicEntitySet entitySet,
            string excelFile,
            string? sheetName = null,
            bool append = false)
        {
            var workbook = new Workbook(excelFile);
            workbook.Write(entitySet, sheetName, append);
            workbook.Save();
        }

        /// <summary>
        /// 向工作薄写入内容，覆盖工作薄中原有内容
        /// </summary>
        /// <param name="entitySets"></param>
        /// <param name="excelFile"></param>
        /// <param name="append"></param>
        public static void Write(
            DynamicEntitySetCollection entitySets,
            string excelFile,
            bool append = false)
        {
            var workbook = new Workbook(excelFile);
            workbook.Write(entitySets, append);
            workbook.Save();
        }
    }
}